package controllers

import (
	"context"
	"contrib.go.opencensus.io/exporter/prometheus"
	"go.opencensus.io/stats"
	"go.opencensus.io/stats/view"
	"go.opencensus.io/tag"
	"miners-monitor/models/miner"
	"net/http"
)

type PrometheusController struct {
	BaseController
	DefineController DefineController
	MinerAo          miner.MinerAoModel
}

var (
	TagMinerID, _ = tag.NewKey("miner_id")
	TagType, _    = tag.NewKey("type")
	TagName, _    = tag.NewKey("name")
)

var (
	MinerBalance = stats.Float64("miner_balance", "miner balance", "FIL")
	MinerPower   = stats.Float64("miner_power", "miner power", "GiB")
	MinerControl = stats.Float64("miner_control", "miner control", "FIL")
	MinerWorker  = stats.Float64("miner_worker", "miner worker", "FIL")
	MinerOwner   = stats.Float64("miner_owner", "miner owner", "FIL")
)

var (
	MinerBalanceView = &view.View{
		Name:        "miner_balance",
		Description: "miner balance",
		Measure:     MinerBalance,
		Aggregation: view.LastValue(),
		TagKeys:     []tag.Key{TagMinerID, TagType},
	}

	MinerPowerView = &view.View{
		Name:        "miner_power",
		Description: "miner power",
		Measure:     MinerPower,
		Aggregation: view.LastValue(),
		TagKeys:     []tag.Key{TagMinerID, TagType},
	}
	MinerControlView = &view.View{
		Name:        "miner_control",
		Description: "miner control",
		Measure:     MinerControl,
		Aggregation: view.LastValue(),
		TagKeys:     []tag.Key{TagMinerID, TagName},
	}
	MinerWorkerView = &view.View{
		Name:        "miner_worker",
		Description: "miner worker",
		Measure:     MinerWorker,
		Aggregation: view.LastValue(),
		TagKeys:     []tag.Key{TagMinerID, TagName},
	}
	MinerOwnerView = &view.View{
		Name:        "miner_owner",
		Description: "miner owner",
		Measure:     MinerOwner,
		Aggregation: view.LastValue(),
		TagKeys:     []tag.Key{TagMinerID, TagName},
	}
)

var DefaultViews = append([]*view.View{
	MinerBalanceView,
	MinerPowerView,
	MinerControlView,
	MinerWorkerView,
	MinerOwnerView,
})

func (this *PrometheusController) Get_Json() {

	ctx := context.Background()

	if err := view.Register(
		DefaultViews...,
	); err != nil {
		panic(err)
	}

	minerIds := this.MinerAo.GetMinerIds()
	for _, singleMinerId := range minerIds {
		singleTotal := this.DefineController.GetMinerTotalByMinerId(singleMinerId)

		_ = stats.RecordWithTags(ctx, []tag.Mutator{tag.Upsert(TagMinerID, singleMinerId), tag.Upsert(TagType, "total_balance")}, MinerBalance.M(singleTotal.TotalBalanceFloat))
		_ = stats.RecordWithTags(ctx, []tag.Mutator{tag.Upsert(TagMinerID, singleMinerId), tag.Upsert(TagType, "quality_adj_power")}, MinerPower.M(singleTotal.QualityAdjPowerFloat))
		_ = stats.RecordWithTags(ctx, []tag.Mutator{tag.Upsert(TagMinerID, singleMinerId), tag.Upsert(TagName, "owner")}, MinerOwner.M(singleTotal.OwnerBalanceFloat))
		_ = stats.RecordWithTags(ctx, []tag.Mutator{tag.Upsert(TagMinerID, singleMinerId), tag.Upsert(TagName, "worker")}, MinerWorker.M(singleTotal.WorkerBalanceFloat))
		_ = stats.RecordWithTags(ctx, []tag.Mutator{tag.Upsert(TagMinerID, singleMinerId), tag.Upsert(TagName, "control")}, MinerControl.M(singleTotal.ControlBalanceFloat))

	}

	exporter, err := prometheus.NewExporter(prometheus.Options{
		Namespace: "filecoin",
	})
	if err != nil {
		panic(err)
	}
	exporter.ServeHTTP(this.Ctx.GetRawResponseWriter().(http.ResponseWriter), this.Ctx.GetRawRequest().(*http.Request))
}
